﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using VR_ChuangKe.Share.Map;
public enum CircleClearEnum
{
    None,
    Hide,
    Dispose
}
public abstract class BaseScrollCircle : MonoBehaviour
{
    
    public bool IsDraw = false;
    public ScrollRect scrollview
    {
        get
        {
            if (_scrollview == null)
            {
                _scrollview = gameObject.GetComponent<ScrollRect>();
                _scrollview.onValueChanged.AddListener((p) => { OnRefrashPos(circles.ToArray(), _scrollview.content); });
            }
            return _scrollview;
        }
    }
    public RectTransform rt { get { if (_rt == null) _rt = gameObject.GetComponent<RectTransform>(); return _rt; } }
    private RectTransform _rt;
    private ScrollRect _scrollview;
    private List<ScrollCircleItem> circles = new List<ScrollCircleItem>();
    private void OnEnable()
    {
        CancelInvoke("RefrashItems");
        Invoke("RefrashItems", 0.2f);
    }
    private void Start()
    {
        CancelInvoke("RefrashItems");
        Invoke("RefrashItems", 0.2f);
    }

    protected virtual void OnDrawGizmos()
    {
        if (IsDraw)
        {
            Gizmos.color = Color.red;
            ScrollCircleItem[] scs = circles.ToArray();
            for (int i = 0; i < scs.Length; i++)
            {
                Vector2 ll = scs[i].GetPos();
                Vector2 ls = scs[i].GetSize();
                Vector2 lr = new Vector2(ll.x + ls.x, ll.y - ls.y);
                Vector3 wl = scrollview.content.TransformPoint(new Vector3(ll.x, ll.y, 0));
                Vector3 wr = scrollview.content.TransformPoint(new Vector3(lr.x, lr.y, 0));

                Gizmos.DrawLine(wl, wl + Vector3.right * Mathf.Abs(wr.x - wl.x));
                Gizmos.DrawLine(wr, wr + Vector3.left * Mathf.Abs(wr.x - wl.x));
                Gizmos.DrawLine(wl, wl + Vector3.down * Mathf.Abs(wr.y - wl.y));
                Gizmos.DrawLine(wr, wr + Vector3.up * Mathf.Abs(wr.y - wl.y));
            }
            Gizmos.color = Color.yellow;
            Rect rect = rt.rect;

            Vector3 swl = scrollview.transform.TransformPoint(new Vector3(rect.x, rect.y + rect.height, 0));
            Vector3 swr = scrollview.transform.TransformPoint(new Vector3(rect.x + rect.width, rect.y, 0));
            Gizmos.DrawLine(swl, swl + Vector3.right * Mathf.Abs(swr.x - swl.x));
            Gizmos.DrawLine(swr, swr + Vector3.left * Mathf.Abs(swr.x - swl.x));
            Gizmos.DrawLine(swl, swl + Vector3.down * Mathf.Abs(swr.y - swl.y));
            Gizmos.DrawLine(swr, swr + Vector3.up * Mathf.Abs(swr.y - swl.y));
        }
    }


    public void AddCircleItem(ScrollCircleItem item, bool isRefrash = false)
    {
        if (!circles.Contains(item))
            circles.Add(item);
        if (isRefrash)
        {
            RefrashItems();
        }
    }

    public void SendMessage(string msg, params object[] data)
    {
        ScrollCircleItem[] scs = circles.ToArray();
        for (int i = 0; i < scs.Length; i++)
        {
            scs[i].OnSendMessage(msg, data);
        }
    }

    public void DelCircleItem(ScrollCircleItem circle, bool isRefrash = false)
    {
        //circle.OnDispose();
        circles.Remove(circle);
        if (isRefrash)
        {
            RefrashItems();
        }
    }

    public void RefrashItems()
    {
        OnRefrashSize(circles.ToArray(), scrollview.content);
        OnRefrashPos(circles.ToArray(), scrollview.content);
    }

    public void Clear(bool isDispose = false)
    {
        if (isDispose)
        {
            ScrollCircleItem[] scs = circles.ToArray();
            for (int i = 0; i < scs.Length; i++)
            {
                scs[i].OnDispose();
            }
        }
        circles.Clear();
    }

    public void Cleanup(CircleClearEnum ctrlEnum)
    {
        if (ctrlEnum != CircleClearEnum.None)
        {
            ScrollCircleItem[] scs = circles.ToArray();
            for (int i = 0; i < scs.Length; i++)
            {
                if (ctrlEnum == CircleClearEnum.Hide)
                    scs[i].OnHide();
                else
                    scs[i].OnDispose();
            }
        }
        circles.Clear();
    }

    public void Release()
    {
        ScrollCircleItem[] scs = circles.ToArray();
        for (int i = 0; i < scs.Length; i++)
        {
            scs[i].OnDispose();
        }
        circles.Clear();
    }
    public ScrollCircleItem[] GetCircleItems()
    {
        return circles.ToArray();
    }
    protected abstract void OnRefrashPos(ScrollCircleItem[] items, RectTransform content);
    protected abstract void OnRefrashSize(ScrollCircleItem[] items, RectTransform content);
}


public class ScrollCircleItem
{
    public object[] data;
    public Rect rect { get { return m_rect; } }
    public RectTransform parent;
    public RectTransform rt { get; private set; }
    private Rect m_rect;
    private Vector2 pos;
    private BCWAction<Vector2>.GBCWObject<ScrollCircleItem> onSizeAction;
    private BCWAction<GameObject>.GBCWObject<ScrollCircleItem> onShowAction;
    private BCWAction.VBCWAction<ScrollCircleItem> onUpdatePosAction;
    private BCWAction.VBCWAction<ScrollCircleItem> onHideAction;
    private BCWAction.VBCWAction<ScrollCircleItem> onDisposetion;
    private BCWAction.VBCWAction<string, object[], ScrollCircleItem> onSendMessage;
    public ScrollCircleItem(BCWAction<GameObject>.GBCWObject<ScrollCircleItem> onShowAction,
        BCWAction.VBCWAction<ScrollCircleItem> onHideAction,
        BCWAction.VBCWAction<ScrollCircleItem> onDisposetion,
        BCWAction.VBCWAction<string, object[], ScrollCircleItem> onSendMessage,
        BCWAction.VBCWAction<ScrollCircleItem> onUpdatePosAction,
        BCWAction<Vector2>.GBCWObject<ScrollCircleItem> onSizeAction)
    {
        this.onShowAction = onShowAction;
        this.onHideAction = onHideAction;
        this.onDisposetion = onDisposetion;
        this.onSizeAction = onSizeAction;
        this.onUpdatePosAction = onUpdatePosAction;
        this.onSendMessage = onSendMessage;
        this.m_rect = new Rect(0, 0, 0, 0);
    }

    public void OnShow()
    {
        if (rt == null)
        {
            GameObject circleObj = onShowAction(this);
            if (circleObj != null)
            {
                rt = circleObj.GetComponent<RectTransform>();
            }
        }
        if (rt != null && onUpdatePosAction != null)
        {
            onUpdatePosAction(this);
        }
    }

    public void OnHide()
    {
        if (rt != null)
        {
            GameObject go = rt.gameObject;
            onHideAction(this);
            rt = null;
        }
    }

    public void OnDispose()
    {
        GameObject go = rt == null ? null : rt.gameObject;
        onDisposetion(this);
        rt = null;
        data = null;
    }
    public void OnSendMessage(string msg, object[] objs)
    {
        if (onSendMessage != null)
        {
            onSendMessage(msg, objs, this);
        }
    }
    public void SetPos(Vector2 pos)
    {
        this.pos = pos;
        m_rect.size = this.onSizeAction(this);
        m_rect.position = new Vector2(pos.x, pos.y - m_rect.height);
    }

    public bool IsHasShow()
    {
        return rt != null;
    }

    public Vector2 GetPos()
    {
        return pos;
    }

    public Vector2 GetSize()
    {
        m_rect.size = this.onSizeAction(this);
        return m_rect.size;
    }
}